package cn.ducis.macaw.core.staticflies.file;

import java.io.File;
import java.util.Map;

import cn.ducis.macaw.util.basic.PathUtil;
import cn.ducis.macaw.core.bPlusTree.BPlusTree;
import cn.ducis.macaw.util.basic.Assert;

/**
 * 此类可用于将大量小文件合并为块文件，并可从块文件中将原本的小文件重新分离出来
 * 
 * @author Yellow
 * @version 1.0
 */
public class StaticFileUtil {
	// 存放所有小文件路径的字符串数组
	private static String[] filePaths;
	// 存放所有块文件中小文件位置映射的总的Map（分离文件时从这个属性根据小文件的路径键获取其位置值）
	@Deprecated
	private static Map<String, String> fileMaps;// 不再将所有文件索引信息存放到一个Map中，采用二级索引
	
	/**
	 * 将属性filePaths中的所有小文件合并为块文件
	 */
	public static void combine() {
		// 记录存放小文件的路径数组被合并完后下一个块开始的序号（从第一个路径开始合并）
		int pathsCount = 0;

		System.out.println(System.currentTimeMillis());
		// 循环将filePaths属性中的所有小文件都合并成块文件
		do {
			pathsCount = BlockFile.joinAtomFiles(filePaths, pathsCount);
		} while (pathsCount < filePaths.length);

		System.out.println(System.currentTimeMillis());
		Index.storeTree(BlockFile.getInedxTree());
		System.out.println(System.currentTimeMillis());
	}

	/**
	 * 查 小文件<br>
	 * 从组合的文件中分离出某一个确定的文件（根据其路径名）
	 * 
	 * @param atomFilePath
	 *            小文件原本的路径字符串
	 * @return 返回存放小文件信息的字节码数组
	 */
	public static byte[] separate(String atomFilePath) {
		Assert.notEmpty(atomFilePath, "Atom file's path string should not be empty.");
//		// 根据小文件路径键获取其对应的值
//		String mergeValue = fileMaps.get(PathUtil.formatPathString(atomFilePath));
		
		System.out.println(System.currentTimeMillis());
		// 获取一级索引树
		BPlusTree indexTree = Index.takeTree();
		// 根据小文件路径从一级索引中获取二级索引文件存放路径后获取二级索引
		Map<String ,String> indexMap= Index.takeFileMaps((String)indexTree.get(atomFilePath));
		String mergeValue = indexMap.get(PathUtil.formatPathString(atomFilePath));
		System.out.println(System.currentTimeMillis());
		// 从值中获取小文件对应块文件的路径
		String blockPath = MapValue.getBlockPath(mergeValue);
		int start = MapValue.getStartEnd(mergeValue)[0];
		int end = MapValue.getStartEnd(mergeValue)[1];
		// TODO 待优化，不将文件全部读出，只拿出需要的部分
		// 已优化，只将需要的小文件信息从流中取出，不用将块文件全部取出，减少内存占用
		byte[] atomFileInfo = FileParse.fileIn(blockPath, start, end);
		System.out.println(System.currentTimeMillis());
		//*********************测试*************************
		FileParse.fileOut(atomFileInfo, "D:\\atomFile.jpg");
		//************************************************
		
		return atomFileInfo;
	}

	/**
	 * 选择存放要合并小文件的文件夹
	 * 
	 * @param dir
	 *            文件夹路径
	 */
	public static void selectFilePaths(String dir) {
		File dirFile = new File(dir);
		// 获取文件夹下所有文件
		String[] files = dirFile.list();
		String[] filePaths = new String[files.length];
		// 将文件夹路径与文件名拼接形成小文件的路径数组
		for (int i = 0; i < files.length; i++) {
			filePaths[i] = dir + "/" + files[i];
		}
		setFilePaths(filePaths);
	}

	public static String[] getFilePaths() {
		return filePaths;
	}

	public static void setFilePaths(String[] filePaths) {
		StaticFileUtil.filePaths = filePaths;
	}

	public static Map getFileMaps() {
		return fileMaps;
	}

	public static void setFileMaps(Map fileMaps) {
		StaticFileUtil.fileMaps = fileMaps;
	}

}
